package com.zzyl.nursing.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.constant.Constants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.IDCardUtils;
import com.zzyl.common.utils.PDFUtil;
import com.zzyl.common.utils.ai.BaiduQianfanAIModelUtil;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.dto.HealthAssessmentDto;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.zzyl.nursing.vo.health.HealthReportVo;
import com.zzyl.oss.AliyunOSSOperator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 健康评估Service业务层处理
 *
 * @author ruoyi
 * @date 2025-09-10
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;
    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private BaiduQianfanAIModelUtil baiduQianfanAIModelUtil;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return getById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 新增健康评估
     *
     * @param healthAssessmentDto 健康评估
     * @return 结果
     */
    @Override
    public Long insertHealthAssessment(HealthAssessmentDto healthAssessmentDto) {
        // 1. 组装提示词
        String prompt = getPrompt(healthAssessmentDto);
        // 2. 使用AI模型对体检报告进行分析
        String reportResult = baiduQianfanAIModelUtil.invoke(prompt);
        // 3. 解析数据（序列化 将JSON字符串转化为Java对象）
        HealthReportVo healthReportVo = JSONUtil.toBean(reportResult, HealthReportVo.class);
        // 4. 将分析结果保存到数据库
        Long id = saveHealthReport(healthReportVo,healthAssessmentDto);
        // 5. 返回id 以便前端做自动查询
        return id;
    }

    /**
     * 将分析结果保存到数据库
     * @param healthReportVo
     * @param healthAssessmentDto
     * @return
     */
    private Long saveHealthReport(HealthReportVo healthReportVo, HealthAssessmentDto healthAssessmentDto) {
        HealthAssessment healthAssessment = new HealthAssessment();
        // 1. 老人数据
        healthAssessment.setElderName(healthAssessmentDto.getElderName());
        String idCard = healthAssessmentDto.getIdCard();
        healthAssessment.setIdCard(idCard);
        healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(idCard));
        healthAssessment.setAge(IDCardUtils.getAgeByIdCard(idCard));
        healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(idCard));
        // 2. 健康评估数据（健康风险等级/健康指数）
        double score = healthReportVo.getHealthAssessment().getHealthIndex();
        healthAssessment.setHealthScore(String.valueOf(score));
        healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel());
        // 3. 入住情况
        healthAssessment.setSuggestionForAdmission(score >= 60 ? 0 : 1); // 建议入住(0:建议，1:不建议)
        String level = nursingLevel(score);
        healthAssessment.setNursingLevelName(level); // 推荐等级名称
        healthAssessment.setAdmissionStatus(1); // 入住情况(0:已入住，1:未入住)
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate()); // 总检日期
        healthAssessment.setPhysicalExamInstitution(healthAssessmentDto.getPhysicalExamInstitution());// 体检机构
        healthAssessment.setPhysicalReportUrl(healthAssessmentDto.getPhysicalReportUrl()); // 体检报告URL链接
        healthAssessment.setAssessmentTime(LocalDateTime.now()); // 评估时间
        // 4. 疾病风险 & 异常数据列表 & 健康系统分值 & 综合总结
        healthAssessment.setDiseaseRisk(JSONUtil.toJsonStr(healthReportVo.getRiskDistribution()));
        healthAssessment.setAbnormalAnalysis(JSONUtil.toJsonStr(healthReportVo.getAbnormalData()));
        healthAssessment.setSystemScore(JSONUtil.toJsonStr(healthReportVo.getSystemScore()));
        healthAssessment.setReportSummary(healthReportVo.getSummarize());
        // 5. 保存到数据库
        save(healthAssessment);
        // 6. 返回id
        return healthAssessment.getId();
    }

    /**
     * 推荐护理等级
     * @param score
     * @return
     */
    private String nursingLevel(double score) {
        if (score < 0 || score > 100){
            throw new BaseException("健康指数异常，评分值超出范围");
        }
        if (score >= 90){
            return "三级护理等级";
        }else if (score >= 80){
            return "二级护理等级";
        }else if (score >= 70){
            return "一级护理等级";
        }else if (score >= 60){
            return "特级级护理等级";
        }
        return "不建议入住";
    }

    /**
     * 组装提示词
     * @param healthAssessmentDto
     * @return
     */
    private String getPrompt(HealthAssessmentDto healthAssessmentDto) {
        // 1. 从redis中获取体检报告内容
        String report = (String)redisTemplate.opsForHash().get(CacheConstants.CACHE_KEY_HEALTH_REPORT, healthAssessmentDto.getIdCard());
        // 2. 拼接提示词
        return StrUtil.format(Constants.HEALTH_REPORT_AI_PROMPT, report);
    }

    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return updateById(healthAssessment) ? 1 : 0;
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 上传文件
     *
     * @param idCardNo
     * @param file
     * @return
     */
    @Override
    public String upload(String idCardNo, MultipartFile file) throws Exception {
        // 1. 上传文件至OSS
        String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
        // 2. 读取PDF文件的内容
        String pdfContent = PDFUtil.pdfToString(file.getInputStream());
        if (StrUtil.isBlank(pdfContent)) {
            throw new BaseException("体检报告PDF文件内容为空");
        }
        // 3. 存储内容到redis Hash
        redisTemplate.opsForHash().put(CacheConstants.CACHE_KEY_HEALTH_REPORT, idCardNo, pdfContent);
        redisTemplate.expire(CacheConstants.CACHE_KEY_HEALTH_REPORT, 300, TimeUnit.SECONDS);
        // 4. 返回url
        return url;
    }
}
